import { triggerEvent } from '@cornerstonejs/core';
import * as annotationStateManagement from '../../../stateManagement/annotation';
import interpolate from '../../contours/interpolation/interpolate';
import type { InterpolationViewportData } from '../../../types/InterpolationTypes';
import getInterpolationData from '../../contours/interpolation/getInterpolationData';
import type { InterpolationROIAnnotation } from '../../../types/ToolSpecificAnnotationTypes';
import EventTypes from '../../../enums/Events';
import type { AnnotationInterpolationRemovedEventDetail } from '../../../types/EventTypes';

/**
 * deleteRelatedAnnotations - Delete the same interpolation uid on deleting one of them.
 *
 * @param eventData - Object.
 * @returns null
 */
export default function deleteRelatedAnnotations(
  viewportData: InterpolationViewportData
) {
  const { annotation } = viewportData;
  const interpolationAnnotations = getInterpolationData(viewportData, [
    { key: 'interpolationUID', value: viewportData.interpolationUID },
  ]);

  const referencedSliceIndex = annotation.metadata.sliceIndex as number;
  let minInterpolation = -1;
  let maxInterpolation = viewportData.sliceData.numberOfSlices;
  for (const [sliceIndex, annotations] of interpolationAnnotations.entries()) {
    if (sliceIndex === referencedSliceIndex) {
      continue;
    }
    const nonInterpolated = annotations.find(
      (annotation) => !annotation.autoGenerated
    );
    if (!nonInterpolated) {
      continue;
    }
    if (sliceIndex < referencedSliceIndex) {
      minInterpolation = Math.max(sliceIndex, minInterpolation);
    } else {
      maxInterpolation = Math.min(sliceIndex, maxInterpolation);
    }
  }

  const removedAnnotations = [];
  for (const [sliceIndex, annotations] of interpolationAnnotations.entries()) {
    if (
      sliceIndex <= minInterpolation ||
      sliceIndex >= maxInterpolation ||
      sliceIndex === referencedSliceIndex
    ) {
      continue;
    }
    annotations.forEach((annotationToDelete) => {
      if (annotationToDelete.autoGenerated) {
        annotationStateManagement.state.removeAnnotation(
          annotationToDelete.annotationUID
        );
        removedAnnotations.push(annotationToDelete);
      }
    });
  }

  if (removedAnnotations.length) {
    const eventDetails: AnnotationInterpolationRemovedEventDetail = {
      annotations: removedAnnotations,
      element: viewportData.viewport.element,
      viewportId: viewportData.viewport.id,
      renderingEngineId: viewportData.viewport.getRenderingEngine().id,
    };

    triggerEvent(
      viewportData.viewport.element,
      EventTypes.INTERPOLATED_ANNOTATIONS_REMOVED,
      eventDetails
    );
  }

  if (
    minInterpolation >= 0 &&
    maxInterpolation < viewportData.sliceData.numberOfSlices
  ) {
    const nextAnnotation = interpolationAnnotations.get(
      maxInterpolation
    )[0] as InterpolationROIAnnotation;
    // Trigger interpolation for the next non-interpolated annotation
    const viewportNewData: InterpolationViewportData = {
      viewport: viewportData.viewport,
      sliceData: {
        numberOfSlices: viewportData.sliceData.numberOfSlices,
        imageIndex: nextAnnotation.metadata.sliceIndex as number,
      },
      annotation: nextAnnotation,
      interpolationUID: nextAnnotation.interpolationUID,
    };
    interpolate(viewportNewData);
  }
}
